package com.smartstate.ems.quartz;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.smartstate.ems.core.ScheduleConstants;
import com.smartstate.ems.dto.EquipmentDTO;
import com.smartstate.ems.entity.*;
import com.smartstate.ems.mapper.*;
import com.smartstate.ems.service.IQuartzJobService;
import com.smartstate.ems.util.QuartzUtils;
import com.smartstate.ems.entity.*;
import com.smartstate.ems.mapper.*;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 根据设备类型查询实时数据,并落入TD  V2.0版本
 */
@Log4j2
@Component("quartzOptimize")
//TODO 使用优化后的定时任务，就把quartzOptimize改为quartz
public class QuartzMethodsOptimize {

    @Resource
    private EquipmentConfigMapper equipmentConfigMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    ElectricMeterMapper electricMeterMapper;

    @Autowired
    GasMapper gasMapper;

    @Autowired
    SteamMapper steamMapper;

    @Resource
    private ObjMoudelMapper objMoudelMapper;

    @Resource
    private ObjMiddleMapper objMiddleMapper;

    @Resource
    private WaterMeterMapper waterMeterMapper;

    @Autowired
    SortingMapper sortingMapper;

    @Autowired
    DehumidifierTDMapper dehumidifierMapper;

    @Autowired
    EquipmentMapper equipmentMapper;

    @Autowired
    QuartzMapper quartzMapper;

    @Autowired
    IQuartzJobService iQuartzJobService;


    @Autowired
    RedisTemplate redisTemplate;

    ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newCachedThreadPool();

    /**
     * 存放上次的值
     * key:dataId
     * value:上次读取到的值
     */
    private HashMap<String, Float> hashMap = new HashMap<String, Float>();





    /**
     * 电表类型 ElectricMeter
     *
     * @param id
     */
    public void electricMeter(String id) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    electricMeterMethodOptimize(id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }


    /**
     * 电表类型优化
     */
    public void electricMeterMethodOptimize(String id) throws Exception {
        Equipment equipment = equipmentMapper.selectById(id);
        //根据设备id去Redis中查找该设备的数据
        Map entries = redisTemplate.opsForHash().entries(equipment.getDeviceId());
        List<EquipmentDTO.AddressData> addressDataList = null;
        //根据设备id查询tags
        EquipmentConfiguration configuration = equipmentConfigMapper.selectOne(equipment.getDeviceId());
        if (configuration != null && configuration.getTags() != null && !"".equals(configuration.getTags())) {
            addressDataList = JSONArray.parseArray(configuration.getTags(), EquipmentDTO.AddressData.class);
        }
        //根据deviceId查询楼层id
        String idAndType = getObjId(equipment);

        ElectricMeter electricMeter = new ElectricMeter();
        electricMeter.setEquipment_id(equipment.getId());
        electricMeter.setDeviceId(equipment.getDeviceId());
        electricMeter.setTs(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        electricMeter.setId(IdUtil.simpleUUID());
        electricMeter.setObjId(idAndType);
        //采集上来的设备状态为正常，才会给电表对象里面的值赋值
        if (entries.size() > 0 && "正常".equals(entries.get("type"))) {
            //通过反射获取对象的所有属性
            Class<? extends ElectricMeter> meterClass = electricMeter.getClass();
            Field[] fields = meterClass.getDeclaredFields();
            if (fields.length > 0) {
                //循环遍历所有属性，并赋值
                for (Field field : fields) {
                    //获取属性名 如active_energy
                    String name = field.getName();
                    if (entries.containsKey(name)) { //如果Redis中保存了这个属性，就赋值
                        Field declaredField = meterClass.getDeclaredField(name);
                        declaredField.setAccessible(true);
                        float parseFloat = Float.parseFloat(entries.get(name).toString());
                        //这个属性可能做有补偿值或者做差值计算
                        if (addressDataList != null) {
                            EquipmentDTO.AddressData data = addressDataList.stream().filter(addressData -> addressData.getAttributeName().equals(name)).findAny().orElse(null);
                            if (data != null) {
                                //计算补偿后的值
                                if (data != null && data.getDeviation() != null && !"".equals(data.getDeviation())) {
                                    float deviation = Float.parseFloat(data.getDeviation());
                                    BigDecimal deviationDecimal = new BigDecimal(deviation);
                                    BigDecimal nowBigDecimal = new BigDecimal(parseFloat);
                                    parseFloat = nowBigDecimal.add(deviationDecimal).floatValue();
                                }

                                //这个属性是否做差值计算
                                if (((data.getIsDifference() != null) && (data.getIsDifference().equals("1"))) || ((data.getPostProcessing() != null) && (data.getPostProcessing().equals("差值计算")))) {
                                    //这个属性做差值计算
                                    //拼接这个属性的差值
                                    String det = "det_" + name;
                                    Field detDeclaredField = meterClass.getDeclaredField(det);
                                    detDeclaredField.setAccessible(true);
                                    if (hashMap.get(data.getDataId()) != null) {
                                        //这个属性做差值计算,从hashmap取上次存的值  key:dataId value：上次的值
                                        Float lastFloat = hashMap.get(data.getDataId());
                                        BigDecimal lastBigDecimal = new BigDecimal(lastFloat);
                                        BigDecimal nowBigDecimal = new BigDecimal(parseFloat);
                                        float v = nowBigDecimal.subtract(lastBigDecimal).floatValue();
                                        detDeclaredField.set(electricMeter, v);
                                        //把当前读取到的值存进去
                                        hashMap.put(data.getDataId(), parseFloat);
                                    } else {
                                        detDeclaredField.set(electricMeter, 0);
                                        hashMap.put(data.getDataId(), parseFloat);
                                    }
                                } else if ((data.getIsDifference() == null || data.getPostProcessing() == null || data.getIsDifference().equals("0") || (!(data.getPostProcessing().equals("差值计算")))) && hashMap.get(data.getDataId()) != null) {
                                    //不做差值，就把以前存的东西删掉
                                    hashMap.remove(data.getDataId());
                                }
                            }
                        }
                        declaredField.set(electricMeter, parseFloat);
                    }
                }
            }
        }
        boolean b = electricMeterMapper.addElectricMeter(electricMeter);
    }

    /**
     * 水表类型
     *
     * @param id
     */
    public void WaterMeter(String id) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    WaterMeterMethodOptimize(id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    /**
     * 水表类型优化
     */
    public void WaterMeterMethodOptimize(String id) throws Exception {
        Equipment equipment = equipmentMapper.selectById(id);
        //根据设备id去Redis中查找该设备的数据
        Map entries = redisTemplate.opsForHash().entries(equipment.getDeviceId());
        List<EquipmentDTO.AddressData> addressDataList = null;
        //根据设备id查询tags
        EquipmentConfiguration configuration = equipmentConfigMapper.selectOne(equipment.getDeviceId());
        if (configuration != null && configuration.getTags() != null && !"".equals(configuration.getTags())) {
            addressDataList = JSONArray.parseArray(configuration.getTags(), EquipmentDTO.AddressData.class);
        }
        //根据deviceId查询楼层id
        String idAndType = getObjId(equipment);
        WaterMeter waterMeter = new WaterMeter();
        waterMeter.setEquipment_id(equipment.getId());
        waterMeter.setId(IdUtil.simpleUUID());
        waterMeter.setTs(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        waterMeter.setObjId(idAndType);
        waterMeter.setDeviceId(equipment.getDeviceId());
        //采集上来的设备状态为正常，才会给电表对象里面的值赋值
        if (entries.size() > 0 && "正常".equals(entries.get("type"))) {
            //通过反射获取对象的所有属性
            Class<? extends WaterMeter> waterMeterClass = waterMeter.getClass();
            Field[] fields = waterMeterClass.getDeclaredFields();
            if (fields.length > 0) {
                //循环遍历所有属性，并赋值
                for (Field field : fields) {
                    //获取属性名 如active_energy
                    String name = field.getName();
                    if (entries.containsKey(name)) { //如果Redis中保存了这个属性，就赋值
                        Field declaredField = waterMeterClass.getDeclaredField(name);
                        declaredField.setAccessible(true);
                        float parseFloat = Float.parseFloat(entries.get(name).toString());
                        //这个属性可能做有补偿值或者做差值计算
                        if (addressDataList != null) {
                            EquipmentDTO.AddressData data = addressDataList.stream().filter(addressData -> addressData.getAttributeName().equals(name)).findAny().orElse(null);
                            if (data!= null) {
                                //计算补偿后的值
                                if (data != null && data.getDeviation() != null && !"".equals(data.getDeviation())) {
                                    float deviation = Float.parseFloat(data.getDeviation());
                                    BigDecimal deviationDecimal = new BigDecimal(deviation);
                                    BigDecimal nowBigDecimal = new BigDecimal(parseFloat);
                                    parseFloat = nowBigDecimal.add(deviationDecimal).floatValue();
                                }

                                //这个属性是否做差值计算
                                if (((data.getIsDifference() != null) && (data.getIsDifference().equals("1"))) || ((data.getPostProcessing() != null) && (data.getPostProcessing().equals("差值计算")))) {
                                    //这个属性做差值计算
                                    //拼接这个属性的差值
                                    String det = "det_" + name;
                                    Field detDeclaredField = waterMeterClass.getDeclaredField(det);
                                    detDeclaredField.setAccessible(true);
                                    if (hashMap.get(data.getDataId()) != null) {
                                        //这个属性做差值计算,从hashmap取上次存的值  key:dataId value：上次的值
                                        Float lastFloat = hashMap.get(data.getDataId());
                                        BigDecimal lastBigDecimal = new BigDecimal(lastFloat);
                                        BigDecimal nowBigDecimal = new BigDecimal(parseFloat);
                                        float v = nowBigDecimal.subtract(lastBigDecimal).floatValue();
                                        detDeclaredField.set(waterMeter, v);
                                        //把当前读取到的值存进去
                                        hashMap.put(data.getDataId(), parseFloat);
                                    } else {
                                        detDeclaredField.set(waterMeter, 0);
                                        hashMap.put(data.getDataId(), parseFloat);
                                    }
                                } else if ((data.getIsDifference() == null || data.getPostProcessing() == null || data.getIsDifference().equals("0") || (!(data.getPostProcessing().equals("差值计算")))) && hashMap.get(data.getDataId()) != null) {
                                    //不做差值，就把以前存的东西删掉
                                    hashMap.remove(data.getDataId());
                                }
                            }
                        }
                        declaredField.set(waterMeter, parseFloat);
                    }
                }
            }
        }
        boolean b = waterMeterMapper.addWaterMeter(waterMeter);

    }

    /**
     * 天然气表方法
     *
     * @param id
     */
    public void getGas(String id) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    GasMethodOptimize(id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    /**
     * 天然气表类型优化
     */
    public void GasMethodOptimize(String id) throws Exception {
        Equipment equipment = equipmentMapper.selectById(id);
        //根据设备id去Redis中查找该设备的数据
        Map entries = redisTemplate.opsForHash().entries(equipment.getDeviceId());
        List<EquipmentDTO.AddressData> addressDataList = null;
        //根据设备id查询tags
        EquipmentConfiguration configuration = equipmentConfigMapper.selectOne(equipment.getDeviceId());
        if (configuration != null && configuration.getTags() != null && !"".equals(configuration.getTags())) {
            addressDataList = JSONArray.parseArray(configuration.getTags(), EquipmentDTO.AddressData.class);
        }
        //根据deviceId查询楼层id
        String idAndType = getObjId(equipment);

        Gas gas = new Gas();
        gas.setEquipment_id(equipment.getId());
        gas.setId(IdUtil.simpleUUID());
        gas.setTs(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        gas.setObjId(idAndType);
        gas.setDeviceId(equipment.getDeviceId());
        //采集上来的设备状态为正常，才会给电表对象里面的值赋值
        if (entries.size() > 0 && "正常".equals(entries.get("type"))) {
            //通过反射获取对象的所有属性
            Class<? extends Gas> gasClass = gas.getClass();
            Field[] fields = gasClass.getDeclaredFields();
            if (fields.length > 0) {
                //循环遍历所有属性，并赋值
                for (Field field : fields) {
                    //获取属性名
                    String name = field.getName();
                    if (entries.containsKey(name)) { //如果Redis中保存了这个属性，就赋值
                        Field declaredField = gasClass.getDeclaredField(name);
                        declaredField.setAccessible(true);
                        float parseFloat = Float.parseFloat(entries.get(name).toString());
                        //这个属性可能做有补偿值或者做差值计算
                        if (addressDataList != null) {
                            EquipmentDTO.AddressData data = addressDataList.stream().filter(addressData -> addressData.getAttributeName().equals(name)).findAny().orElse(null);
                            if (data != null) {
                                //计算补偿后的值
                                if (data != null && data.getDeviation() != null && !"".equals(data.getDeviation())) {
                                    float deviation = Float.parseFloat(data.getDeviation());
                                    BigDecimal deviationDecimal = new BigDecimal(deviation);
                                    BigDecimal nowBigDecimal = new BigDecimal(parseFloat);
                                    parseFloat = nowBigDecimal.add(deviationDecimal).floatValue();
                                }

                                //这个属性是否做差值计算
                                if (((data.getIsDifference() != null) && (data.getIsDifference().equals("1"))) || ((data.getPostProcessing() != null) && (data.getPostProcessing().equals("差值计算")))) {
                                    //这个属性做差值计算
                                    //拼接这个属性的差值
                                    String det = "det_" + name;
                                    Field detDeclaredField = gasClass.getDeclaredField(det);
                                    detDeclaredField.setAccessible(true);
                                    if (hashMap.get(data.getDataId()) != null) {
                                        //这个属性做差值计算,从hashmap取上次存的值  key:dataId value：上次的值
                                        Float lastFloat = hashMap.get(data.getDataId());
                                        BigDecimal lastBigDecimal = new BigDecimal(lastFloat);
                                        BigDecimal nowBigDecimal = new BigDecimal(parseFloat);
                                        float v = nowBigDecimal.subtract(lastBigDecimal).floatValue();
                                        detDeclaredField.set(gas, v);
                                        //把当前读取到的值存进去
                                        hashMap.put(data.getDataId(), parseFloat);
                                    } else {
                                        detDeclaredField.set(gas, 0);
                                        hashMap.put(data.getDataId(), parseFloat);
                                    }
                                } else if ((data.getIsDifference() == null || data.getPostProcessing() == null || data.getIsDifference().equals("0") || (!(data.getPostProcessing().equals("差值计算")))) && hashMap.get(data.getDataId()) != null) {
                                    //不做差值，就把以前存的东西删掉
                                    hashMap.remove(data.getDataId());
                                }
                            }
                        }
                        declaredField.set(gas, parseFloat);
                    }
                }
            }
        }
        boolean b = gasMapper.addGas(gas);
    }


    /**
     * 工业看板类型
     *
     * @param id
     */
    public void storting(String id) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    stortingMethodOptimize(id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    /**
     * 工业看板优化
     *
     * @param id
     */
    public void stortingMethodOptimize(String id) throws Exception {
        try {
            Equipment equipment = equipmentMapper.selectById(id);
            Map entries = redisTemplate.opsForHash().entries(equipment.getDeviceId());
            List<EquipmentDTO.AddressData> addressDataList = null;
            //根据设备id查询tags
            EquipmentConfiguration configuration = equipmentConfigMapper.selectOne(equipment.getDeviceId());
            if (configuration != null && configuration.getTags() != null && !"".equals(configuration.getTags())) {
                addressDataList = JSONArray.parseArray(configuration.getTags(), EquipmentDTO.AddressData.class);
            }
            //根据deviceId查询楼层id
            String idAndType = getObjId(equipment);

            Sorting sorting = new Sorting();
            sorting.setEquipment_id(equipment.getId());
            sorting.setTs(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            sorting.setObjId(idAndType);
            sorting.setDeviceId(equipment.getDeviceId());
            String s1 = IdUtil.simpleUUID();
            sorting.setUid(s1);
            sorting.setId(s1);
            if (entries.size() > 0 && "正常".equals(entries.get("type"))) {
                Class<? extends Sorting> sortingClass = sorting.getClass();
                //获取这个对象的所有属性
                Field[] fields = sortingClass.getDeclaredFields();
                if (fields.length > 0) {
                    //循环遍历所有属性，并赋值
                    for (Field field : fields) {
                        //获取属性名
                        String name = field.getName();
                        if (entries.containsKey(name)) {
                            Field declaredField = sortingClass.getDeclaredField(name);
                            declaredField.setAccessible(true);
                            float parseFloat = Float.parseFloat(entries.get(name).toString());
                            if (addressDataList != null) {
                                EquipmentDTO.AddressData data = addressDataList.stream().filter(addressData -> addressData.getAttributeName().equals(name)).findAny().orElse(null);
                                //这个属性是否做补偿值计算
                                if (data != null && data.getDeviation() != null && !"".equals(data.getDeviation())) {
                                    float deviation = Float.parseFloat(data.getDeviation());
                                    BigDecimal deviationDecimal = new BigDecimal(deviation);
                                    BigDecimal nowBigDecimal = new BigDecimal(parseFloat);
                                    parseFloat = nowBigDecimal.add(deviationDecimal).floatValue();
                                }
                            }
                            declaredField.set(sorting, parseFloat);

                        }
                    }
                }

            }
            boolean b = sortingMapper.addSorting(sorting);
        } catch (Exception e) {
            throw new Exception(e);
        }
    }


    /**
     * 除湿机类型
     */
    public void dehumidifier(String id) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    dehumidifierMethodOptimize(id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    /**
     * 除湿机类型优化
     */
    public void dehumidifierMethodOptimize(String id) throws Exception {
        Equipment equipment = equipmentMapper.selectById(id);
        //根据设备id去Redis中查找该设备的数据
        Map entries = redisTemplate.opsForHash().entries(equipment.getDeviceId());
        List<EquipmentDTO.AddressData> addressDataList = null;
        //根据设备id查询tags
        EquipmentConfiguration configuration = equipmentConfigMapper.selectOne(equipment.getDeviceId());
        if (configuration != null && configuration.getTags() != null && !"".equals(configuration.getTags())) {
            addressDataList = JSONArray.parseArray(configuration.getTags(), EquipmentDTO.AddressData.class);
        }
        //根据deviceId查询楼层id
        String idAndType = getObjId(equipment);

        Dehumidifier dehumidifier = new Dehumidifier();
        dehumidifier.setId(IdUtil.simpleUUID());
        dehumidifier.setTs(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        dehumidifier.setDeviceId(equipment.getDeviceId());
        dehumidifier.setEquipment_id(equipment.getId());
        dehumidifier.setObjId(idAndType);
        //采集上来的设备状态为正常，才会给电表对象里面的值赋值
        if (entries.size() > 0 && "正常".equals(entries.get("type"))) {
            //通过反射获取对象的所有属性
            Class<? extends Dehumidifier> dehumidifierClass = dehumidifier.getClass();
            Field[] fields = dehumidifierClass.getDeclaredFields();
            if (fields.length > 0) {
                //循环遍历所有属性，并赋值
                for (Field field : fields) {
                    //获取属性名
                    String name = field.getName();
                    if (entries.containsKey(name)) { //如果Redis中保存了这个属性，就赋值
                        Field declaredField = dehumidifierClass.getDeclaredField(name);
                        declaredField.setAccessible(true);
                        float parseFloat = Float.parseFloat(entries.get(name).toString());
                        //这个属性可能做有补偿值或者做差值计算
                        if (addressDataList != null) {
                            EquipmentDTO.AddressData data = addressDataList.stream().filter(addressData -> addressData.getAttributeName().equals(name)).findAny().orElse(null);
                            //计算补偿后的值
                            if (data != null && data.getDeviation() != null && !"".equals(data.getDeviation())) {
                                float deviation = Float.parseFloat(data.getDeviation());
                                BigDecimal deviationDecimal = new BigDecimal(deviation);
                                BigDecimal nowBigDecimal = new BigDecimal(parseFloat);
                                parseFloat = nowBigDecimal.add(deviationDecimal).floatValue();
                            }
                        }
                        declaredField.set(dehumidifier, parseFloat);
                    }
                }
            }
        }
        boolean b = dehumidifierMapper.addDehumidifier(dehumidifier);
    }


    /**
     * 蒸汽
     *
     * @param id
     */
    public void getSteam(String id) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    steamMethodOptimize(id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    /**
     * 蒸汽表类型优化
     */
    public void steamMethodOptimize(String id) throws Exception {
        Equipment equipment = equipmentMapper.selectById(id);
        //根据设备id去Redis中查找该设备的数据
        Map entries = redisTemplate.opsForHash().entries(equipment.getDeviceId());
        List<EquipmentDTO.AddressData> addressDataList = null;
        //根据设备id查询tags
        EquipmentConfiguration configuration = equipmentConfigMapper.selectOne(equipment.getDeviceId());
        if (configuration != null && configuration.getTags() != null && !"".equals(configuration.getTags())) {
            addressDataList = JSONArray.parseArray(configuration.getTags(), EquipmentDTO.AddressData.class);
        }
        //根据deviceId查询楼层id
        String idAndType = getObjId(equipment);
        Steam steam = new Steam();
        steam.setEquipment_id(equipment.getId());
        steam.setId(IdUtil.simpleUUID());
        steam.setTs(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        steam.setObjId(idAndType);
        steam.setDeviceId(equipment.getDeviceId());
        //采集上来的设备状态为正常，才会给电表对象里面的值赋值
        if (entries.size() > 0 && "正常".equals(entries.get("type"))) {
            //通过反射获取对象的所有属性
            Class<? extends Steam> steamClass = steam.getClass();
            Field[] fields = steamClass.getDeclaredFields();
            if (fields.length > 0) {
                //循环遍历所有属性，并赋值
                for (Field field : fields) {
                    //获取属性名 如active_energy
                    String name = field.getName();
                    if (entries.containsKey(name)) { //如果Redis中保存了这个属性，就赋值
                        Field declaredField = steamClass.getDeclaredField(name);
                        declaredField.setAccessible(true);
                        float parseFloat = Float.parseFloat(entries.get(name).toString());
                        //这个属性可能做有补偿值或者做差值计算
                        if (addressDataList != null) {
                            EquipmentDTO.AddressData data = addressDataList.stream().filter(addressData -> addressData.getAttributeName().equals(name)).findAny().orElse(null);
                            if (data != null) {
                                //计算补偿后的值
                                if (data != null && data.getDeviation() != null && !"".equals(data.getDeviation())) {
                                    float deviation = Float.parseFloat(data.getDeviation());
                                    BigDecimal deviationDecimal = new BigDecimal(deviation);
                                    BigDecimal nowBigDecimal = new BigDecimal(parseFloat);
                                    parseFloat = nowBigDecimal.add(deviationDecimal).floatValue();
                                }

                                //这个属性是否做差值计算
                                if (data != null && (((data.getIsDifference() != null) && (data.getIsDifference().equals("1"))) || ((data.getPostProcessing() != null) && (data.getPostProcessing().equals("差值计算"))))) {
                                    //这个属性做差值计算
                                    //拼接这个属性的差值
                                    String det = "det_" + name;
                                    Field detDeclaredField = steamClass.getDeclaredField(det);
                                    detDeclaredField.setAccessible(true);
                                    if (hashMap.get(data.getDataId()) != null) {
                                        //这个属性做差值计算,从hashmap取上次存的值  key:dataId value：上次的值
                                        Float lastFloat = hashMap.get(data.getDataId());
                                        BigDecimal lastBigDecimal = new BigDecimal(lastFloat);
                                        BigDecimal nowBigDecimal = new BigDecimal(parseFloat);
                                        float v = nowBigDecimal.subtract(lastBigDecimal).floatValue();
                                        detDeclaredField.set(steam, v);
                                        //把当前读取到的值存进去
                                        hashMap.put(data.getDataId(), parseFloat);
                                    } else {
                                        detDeclaredField.set(steam, 0);
                                        hashMap.put(data.getDataId(), parseFloat);
                                    }
                                } else if ((data.getIsDifference() == null || data.getPostProcessing() == null || data.getIsDifference().equals("0") || (!(data.getPostProcessing().equals("差值计算")))) && hashMap.get(data.getDataId()) != null) {
                                    //不做差值，就把以前存的东西删掉
                                    hashMap.remove(data.getDataId());
                                }
                            }
                        }
                        declaredField.set(steam, parseFloat);
                    }
                }
            }
        }
        boolean b = steamMapper.addSteam(steam);
    }

    private String getObjId(Equipment equipment) {
        List<String> objId = objMiddleMapper.findByDeviceId(equipment.getDeviceId());
        if (objId != null) {
            for (String s : objId) {
                String type = objMoudelMapper.findIdAndType(s, "1");
                if (type != null) {
                    return type;
                }
            }
        }
        return "";
    }

    /**
     * 每过十分钟，判断一下设备有没有修改
     */
    public void updateQuartz(String id) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    updateQuartzMethod(id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    public void updateQuartzMethod(String param) throws Exception {
        try {
            //当前时间
            DateTime nowTime = new DateTime();
            //前十分钟的时间
            DateTime tenTimeAgo = nowTime.offsetNew(DateField.MINUTE, -10);
            List<Equipment> equipmentList = equipmentMapper.findByTenTimeAgo(nowTime, tenTimeAgo);
            if (equipmentList.size() > 0) {
                for (Equipment equipment : equipmentList) {
                    String S = QuartzUtils.type(equipment.getId(), equipment.getType());
                    QuartzJob job = quartzMapper.selectByInvokeTarget(S);
                    if (job != null) {
                        //数据库中已经存在这个设备的定时任务，就更新定时任务
                        String type = QuartzUtils.type(equipment.getId(), equipment.getType());  //根据设备类型调用指定的方法
                        job.setInvokeTarget(type);
                        String cycle = QuartzUtils.cycle(equipment.getCycle()); //定时任务执行周期
                        job.setCronExpression(cycle);
                        job.setJobName(equipment.getDeviceId());
                        int updateJob = iQuartzJobService.updateJob(job);
                        if (updateJob > 0) {
                            log.info(equipment.getDeviceId() + "更新定时任务成功");
                        } else {
                            log.info(equipment.getDeviceId() + "更新定时任务失败");
                        }
                    } else {
                        //数据库中还未存在这个定时任务，就新增
                        QuartzJob quartzJob = new QuartzJob();
                        String corn = QuartzUtils.cycle(equipment.getCycle());
                        quartzJob.setCronExpression(corn);
                        quartzJob.setJobName(equipment.getDeviceId());
                        quartzJob.setJobGroup("DEFAULT");
                        String invokeTarget = QuartzUtils.type(equipment.getId(), equipment.getType());
                        quartzJob.setInvokeTarget(invokeTarget);
                        quartzJob.setMisfirePolicy(ScheduleConstants.MISFIRE_IGNORE_MISFIRES);
                        quartzJob.setConcurrent("1");
                        quartzJob.setStatus("0");
                        quartzJob.setRemark("系统自动创建" + equipment.getDeviceId() + "的任务");
                        int insert = iQuartzJobService.insertJob(quartzJob);
                        if (insert > 0) {
                            log.info(equipment.getDeviceId() + "新增定时任务成功");
                        } else {
                            log.info(equipment.getDeviceId() + "新增定时任务失败");
                        }
                    }

                }
            } else {
//                System.out.println("暂无定时任务需要修改");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void defaultMethods(String id) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    defaultMethod(id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    /**
     * TODO 别的设备类型不知道要不要采集数据，就先留着
     *
     * @param param
     */
    public void defaultMethod(String param) throws Exception {


    }

    public void PLCCollect(String id) {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        RequestContextHolder.setRequestAttributes(sra, true);
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    PLCCollectMethod(id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    // plc采集方式
    public void PLCCollectMethod(String param) throws Exception {

        Equipment equipment = equipmentMapper.selectById(param);
        if (equipment != null) {
            EquipmentConfiguration equipmentConfiguration = equipmentConfigMapper.selectOne(equipment.getDeviceId());
            if (equipmentConfiguration != null && equipmentConfiguration.getTags() != null && !"".equals(equipmentConfiguration.getTags())) {
                List<EquipmentDTO.AddressData> addressDataList = JSONArray.parseArray(equipmentConfiguration.getTags(), EquipmentDTO.AddressData.class);
                addressDataList.stream().forEach(addressData -> {
                    //根据设备id去Redis查找数据
                    Map entries = redisTemplate.opsForHash().entries(equipment.getDeviceId());
                    if (entries.size() > 0) {
                        //Redis中存入的上下限是否报警 longParticleup longParticledown longParticleIsAlarm
                        String up = addressData.getAttributeName() + "up";
                        String down = addressData.getAttributeName() + "down";
                        String IsAlarm = addressData.getAttributeName() + "IsAlarm";
                        String deviation = addressData.getAttributeName() + "deviation";
                        //plc采集的上限 有就保存进tags中
                        if (entries.containsKey(up)) {
                            String stringUp = (entries.get(up).toString());
                            addressData.setUp(stringUp);
                        }
                        //plc采集的下限，有就保存进tags中
                        if (entries.containsKey(down)) {
                            String stringDown = (entries.get(down).toString());
                            addressData.setDown(stringDown);
                        }
                        //plc采集的补偿值，有就保存进tags中
                        if (entries.containsKey(deviation)) {
                            String stringDown = (entries.get(deviation).toString());
                            addressData.setDeviation(stringDown);
                        }
                        //plc采集的是否报警，有就保存进tags中
                        if (entries.containsKey(IsAlarm)) {
                            addressData.setIsAlarm(Boolean.parseBoolean((entries.get(IsAlarm).toString())) ? "1" : "0");
                        }
                    }
                });
                System.out.println("equipmentConfiguration.getTags() = " + addressDataList);
                equipmentConfiguration.setTags(JSON.toJSONString(addressDataList));
                //把保存的tags存入数据库
                equipmentConfigMapper.updateById(equipmentConfiguration);
            }
        }
    }

}
